<?     
define ("GLOBAL_CONFIG", "eb-config.txt");  
$server = '';
$user = '';
$password = '';
$database = '';    

function page_load ()
{
	$action 	= $_GET['action'];
	$table  	= $_GET['table'];
	$start  	= $_GET['start'];
	$stamp  	= $_GET['stamp'];
	$pagesize  	= $_GET['pagesize'];
	if ($action=='backup') 
	{
		echo BackupObject ('SELECT * FROM ' . $table . '', $start, $pagesize, $stamp, $table);
		exit;
	}
	if ($action=='restore') 
	{
		echo RestoreObject ($start, $pagesize, $stamp, $table);
		exit;
	}
	if ($action=='getbackups') 
	{
		echo GetBackups ();
		exit;
	} 
	if ($action=='getobjects') 
	{
		echo GetObjects ();
		exit;
	} 
}
 

function RestoreObject ($start=NULL, $pagesize=100, $dir=NULL, $filename=NULL)
{
	$backupas = '__backup/' . $dir. '__backup/' . $filename . '__' . base64_encode($start) . '.txt';
	if (file_exists($backupas))
	{
		$fp=fopen($backupas,'r');
		$fr=fread ($fp,filesize($backupas));
		fclose ($fp);
		$fr=explode("\n",$fr);
		
		$name=array_shift ($fr);
		$line=explode(',',$name);
		for ($x=0;$x<sizeof($line);$x++)
		{
			$d[]=base64_decode ($line[$x]);
		}
		
		if ($start==0)
		{
			form_database_query('DELETE FROM ' . $filename); 
		}
		
		
		$sql='INSERT INTO ' . $filename . ' (' . implode(',',$d) . ') VALUES ';
		
		$count  = sizeof ($fr); 
		$result = $fr;
		for ($e=0;$e<sizeof($result);$e++)
		{ 
			$line=explode(',',$result[$e]);
			$d=array();
			for ($x=0;$x<sizeof($line);$x++)
			{
				if (strlen($line[$x])==0) $d[]='null';
				else $d[]="'" . str_replace("'",'&apos;', base64_decode ($line[$x])) . "'";
			}
			$query = $sql . '(' . implode (',',$d) . ')';
			form_database_query($query); 
			#echo '<xmp>' . $query . '</xmp><hr>';
		}
		
		$output = '<recordset saveas="'.$backupas.'" filesize="' . filesize($backupas) . '" eof="false"/>';
	}
	else
	{
		$output = '<recordset saveas="'.$backupas.'" filesize="0" eof="true"/>';
	}
	return $output;
}
page_load ();

function BackupObject ($query, $start=NULL, $pagesize=100, $dir=NULL, $filename=NULL)
{
    $xml    = array();
    $name   = array();          
    $result = form_database_query($query); 
	if ($result)
	{
		$x      = mysql_num_fields($result);
		$count  = mysql_num_rows ($result);
		$affect = mysql_affected_rows ($result);
		$estart = microtime (true);
		$cursor = 1;
		
     
		for ($i=0;$i<$x;$i++) $name[]= base64_encode(mysql_field_name($result,$i));         
		
		
		if ($start && $start > 0 && $count > 0)
		{
			mysql_data_seek($result, $start);
		} 
		
		$xml[] = implode (',',$name) . "";
		while($row = mysql_fetch_row($result))  
		{ 
			$field=array();
			for ($i=0;$i<$x;$i++)
			{
			   $field[]=base64_encode($row[$i]);
			}
			$xml[] = implode (',',$field) . "";
			 
			$cursor ++;
			if ($cursor > $pagesize) break;
		}
		
		
		 
		mysql_free_result($result);
		
		if (!is_dir ('__backup')) mkdir ('__backup');
		if (!is_dir ('__backup/' . $dir. '__backup')) mkdir ('__backup/' . $dir. '__backup');
		 
		
		$backupas = '__backup/' . $dir. '__backup/' . $filename . '__' . base64_encode($start) . '.txt';
		$fp=fopen($backupas,$start==0?'w':'a');
		fwrite ($fp,implode("\n",$xml));
		fclose ($fp);
		$output = '<recordset saveas="'.$backupas.'" elapsed="' . $exectime . '" filesize="' . filesize($backupas) . '" count="' . $count . '"/>';
		return $output;
	}
	return '';
}


function GetBackups ()
{ 
	$array=array ();    
	$dirname='__backup';            
	$dh = opendir( $dirname ) or die ("couldn't open directory");        
	$array[]='<backups>';       
	while (! ( ( $file = readdir ( $dh ) ) == false ) ) {               
		if ( is_dir( "$dirname/$file" ) ) 
		{               
			if (preg_match('/(\d+)__backup/',$file,$arr))
			{
				$array[]='<backup date="' . date('m/d/Y H:i:s',$arr[1]/1000) . '" stamp="' . $arr[1] . '"/>';       
			}			  
		}               
	}              
	$array[]='</backups>';        
	closedir( $dh );  
	return implode ('',$array);      
}


function GetObjects ()
{ 
    global $database;
    $xml = array();
    $xml[] = '<!-- GetObjects ' . date ('m/d/Y H:i:s') . ' -->';
    $xml[] = '<tables database="' . $database . '">';
    $result = form_database_query("show table status");
    while($row = mysql_fetch_assoc($result))  
    {
        $xml[] = '<table ';
        $xml[] = ' name="' . $row['Name'] . '"';
        $xml[] = ' size="' . $row['Data_length'] . '"';
        $xml[] = ' type="' . $row['Type'] . '"';
        $xml[] = ' free="' . $row['Data_free'] . '"';
        $xml[] = ' created="' . $row['Create_time'] . '"';
        $xml[] = ' updated="' . $row['Update_time'] . '"';
        $xml[] = '/>';
    }
    $xml[] = '</tables>';
    return implode ("\n", $xml);
}




function generic_data($server,$user,$password,$database,$query) {                                                                
    global $fatal;                                                               
    /* Accessing SQL-Server and querying table */                                                                
    MYSQL_CONNECT($server, $user, $password) or die ( $fatal." Server $server unreachable $user/$password" );                                                               
    MYSQL_SELECT_DB($database) or die ( $fatal." Database unreachable" );                                                                 
    $result = @MYSQL_QUERY(stripslashes($query));                                                               
     if ($result)                                                               
     {                                                               
     }                                                               
     else                                                               
     {                                                               
		print ("<error><![CDATA[<xmp><img src='http://www.cyber8.net/webservices/images/explorer/exclamation.gif' align=top>                                                               
				<b>A fatal MySQL error occured</b>.\n<br />Query:<xmp>                                                                
				" . $query . "</xmp><br />\nError: (" . mysql_errno() . ") <xmp>" . mysql_error() . "</xmp><br>                                                               
				<A HREF='javascript:history.back()'>Please try again</A>]]></error>");                                                               
		MYSQL_CLOSE();                                              
		exit;                                                             
     }                                                                     
    return $result;                                                                 
    MYSQL_CLOSE();                                                               
}                                                               

function form_database_query($query) {                                                               
                                                                   
   global $server;                                                               
   global $user;                                                               
   global $password;                                                               
   global $database;      
   
   $fp=fopen (GLOBAL_CONFIG,'r');
   $fr=fread ($fp, filesize(GLOBAL_CONFIG));
   fclose ($fp);
   foreach (explode ("\n",$fr) as $line)
   {
		parse_str($line); 
   }
   $server 		= $config ['server'];                                                       
   $user 		= $config ['user'];                                                       
   $password 	= $config ['password'];                                                       
   $database	= $config ['database'];                                                       
   return generic_data($server,$user,$password,$database,$query);                                                                
}                                                 



?>
<html>
<head> 
<link rel="stylesheet" href="style.css"/>  
<title>Untitled Document</title> 
<script language="javascript" src="http://www.cyber8.net/webservices/framework/core/application.js"></script>
<script language="javascript"> 
var pagesize = 100;
var app = Application.create ("EventBuilder Backup");
app.using (featherweight.core); 
app.using (featherweight.web); 
app.onload = onstart;
function onstart ()
{
	document.title = app.name;
	var views = {
		main : View.create ('main', 'dwork', function ()
		{
			var htm=[];
			htm.push ('<input style="padding:4pt;font-weight:bold" type="button" '+((Controller.backingup||Controller.restoring)?'disabled':'')+' value="Backup" onclick="dobackup()"/>'); 
			
			if (Controller.backups && Controller.backups.length>0)
			{
				htm.push ('&nbsp;Backups on file: ');
				htm.push ('<select id="drrestore" onchange="document.getElementById(\'iprestore\').disabled=this.selectedIndex==0"><option>(choose)');
				for (var x in Controller.backups)
				{
					htm.push ('<option value="' + Controller.backups[x].stamp + '">' + Controller.backups[x].date);
				}
				htm.push ('</select>');
				htm.push ('<input id="iprestore" '+((Controller.backingup||Controller.restoring)?'disabled':'')+'');
				htm.push (' style="padding:4pt;font-weight:bold"');
				htm.push (' type="button" value="Restore"');
				htm.push (' onclick="dorestore(document.getElementById(\'drrestore\').value)"');
				htm.push (' />');
			}
			
			htm.push ('<table bgcolor=silver cellspacing=1 cellpadding=4 width="100%">');
			htm.push ('<tr bgcolor=white>' + 
					'<td class="small">&nbsp;</td>' + 
					'<td class="small" style="color:gray">name</td>' + 
					'<td class="small" style="color:gray">size</td>' + 
					'<td class="small" style="color:gray">created</td>' + 
					'<td class="small" style="color:gray">status</td>' + 
					'<td width="100%">&nbsp;</td>' + 
					'</tr>');
			for (var x in Controller.tables)
			{
				htm.push (Controller.tables[x].draw());
			}
			htm.push ('</table>');

			return htm.join ('');
		})
	}
	Controller.main = Event.create ('main');
	for (var x in views) Controller.main.add (views[x]);
	
	DATA_URL = location.href
	Webservice.add ('getobjects', ongetobjects);
	Webservice.add ('getbackups', ongetbackups);
	Webservice.add ('backup', function() {});
	Webservice.add ('restore', function() {});
	Webservice.getbackups ();
}

function ongetbackups (data)
{
	var dom = XmlDocument.create();  
	if (dom.loadXML(data))
	{
		var backups  = dom.getElementsByTagName ('backup'); 
		Controller.backups=[];
		for (var e=0;e<backups.length;e++)
		{
		    var o={  };
			for (var x=0;x<backups[e].attributes.length;x++) o[backups[e].attributes[x].name]=backups[e].attributes[x].value;
			o.id = Controller.backups.length;
			Controller.backups.push (o)
		}
		Webservice.getobjects ();
	}
}

function ongetobjects (data)
{
	var dom = XmlDocument.create();  
	if (dom.loadXML(data))
	{
		var tables  = dom.getElementsByTagName ('table'); 
		Controller.tables=[];
		for (var e=0;e<tables.length;e++)
		{
		    var o={ progress:0, count:0, saveas:null, filesize:null,eof:'false' };
			for (var x=0;x<tables[e].attributes.length;x++) o[tables[e].attributes[x].name]=tables[e].attributes[x].value;
			o.draw = function ()
			{
				if (!(Controller.backingup || Controller.restoring)) msg={hue:'#FFFFFF',fore:'#000000',text:'Ready'};
				else if (this.progress == 0) msg={hue:'#f0f0f0',text:'Waiting...',fore:'gray'};
				else if (Controller.restoring&&this.eof=='true') msg={hue:'green',text:'Complete',fore:'white'}; 
				else if (Controller.restoring&&this.id==Controller.index) msg={hue:'navy',text:'Restoring...',fore:'white'}; 
				else if (this.progress >= this.count) msg={hue:'green',text:'Complete',fore:'white'}; 
				else msg={hue:'navy',fore:'white',text:prog(this.progress,this.count,this.progress + ' of ' + this.count + ' rows...')}; 
				var icon=this.id==Controller.index?'/webservices/images/explorer/chrome_throbber_fast_16.gif':'/webservices/images/ico_grid.jpg';
				var state = '';
				if (Controller.backingup) state='Backing up as';
				else if (Controller.restoring) state='Restoring from';
				else if (this.saveas) state='Backed up as';
				var htm = '<tr bgcolor=' + msg.hue + '>' + 
								'<td class="small" style="background-color:white" bgcolor="white"><img src="'+icon+'"></td>' + 
								'<td class="small" style="color:'+msg.fore+'" nowrap>' + this.name + '</td>' + 
								'<td class="small" style="color:'+msg.fore+'" nowrap align=rignt>' + this.size + ' bytes</td>' + 
								'<td class="small" style="color:'+msg.fore+'" nowrap>' + this.created + '</td>' + 
								'<td class="small" style="color:'+msg.fore+'" nowrap width="175">' + msg.text + '</td>' + 
								'<td width="100%" style="color:'+msg.fore+'" nowrap class="small">&nbsp;' + 
								(this.saveas?(''+state+': <a style="color:'+msg.fore+'" class="small" href="' + this.saveas + '" target="_blank">' + this.saveas + '</a> ('+this.filesize+' bytes)'):'') +
								'</td>' + 
							'</tr>'; 
				return htm;
			}
			o.backup = function ()
			{
				var id = this.id;
				if (!Controller.backingup) return false;
				var PAGESIZE=this.name=='ebp_event_attachments'?1:pagesize;
				Webservice.backup ('table', this.name, 'start', this.progress, 'pagesize', PAGESIZE, 'stamp', Controller.stamp, function (data)
				{
					var ID=id,dom = XmlDocument.create();  
					if (dom.loadXML(data))
					{
						var root  = dom.getElementsByTagName ('recordset');
						if (root[0])
						{
							Controller.tables[ID].saveas 	= root[0].getAttribute ('saveas');
							Controller.tables[ID].filesize	= root[0].getAttribute ('filesize');
							Controller.tables[ID].count 	= root[0].getAttribute ('count');
							Controller.tables[ID].tmpdata 	= '<xmp>'+data+'</xmp>';
							Controller.tables[ID].progress += PAGESIZE; 
							Controller.main.invoke ();
							if (Controller.tables[ID].progress < parseInt(Controller.tables[ID].count, 10))
							{
								Controller.tables[ID].backup ()
							} 
							else
							{
								Controller.index ++;
								backup();
							}
						} else alert (data);
					} 
				});
			}
			o.restore = function ()
			{
				var id = this.id;
				if (!Controller.restoring) return false;
				Webservice.restore ('table', this.name, 'start', this.progress, 'pagesize', pagesize, 'stamp', Controller.stamp, function (data)
				{
					var ID=id,dom = XmlDocument.create();    
					if (dom.loadXML(data))
					{
						var root  = dom.getElementsByTagName ('recordset');
						if (root[0])
						{
							Controller.tables[ID].saveas 	= root[0].getAttribute ('saveas');
							Controller.tables[ID].filesize	= root[0].getAttribute ('filesize');
							Controller.tables[ID].eof 		= root[0].getAttribute ('eof');
							Controller.tables[ID].tmpdata 	= '<xmp>'+data+'</xmp>';
							Controller.tables[ID].progress += pagesize; 
							Controller.main.invoke ();
							if (Controller.tables[ID].eof=='true')
							{
								Controller.index ++;
								restore();
							} 
							else
							{
								Controller.tables[ID].restore ();
							}
						} else alert (data);
					} 
				});
			}
			o.id = Controller.tables.length;
			Controller.tables.push (o)
		} 
	} 
	Controller.backingup = false;
	Controller.restoring = false;
	Controller.main.invoke();
}
function prog (i,x,t)
{
	var m=t.length,r=Math.floor(m*i/x),o='<u>';
	for (var e=0;e<m;e++) o+='<font color="'+(e<r?'white':'cyan')+'">'+t.substr(e,1)+'</font>';
	return o + '</u>';
}

function stopbackup () { Controller.backingup = false; Controller.main.invoke(); }  
function dobackup ()
{
	Controller.backingup = true;
	Controller.stamp   = new Date().getTime();
	Controller.index = 0;
	backup ();
}
function dorestore (stamp)
{
	if (typeof(stamp)=='undefined'||stamp=='') return confirm('Please select an item to restore!');
	Controller.restoring = true;
	Controller.stamp   = stamp;
	Controller.index = 0;
	restore ();
}
 
function restore ()
{
	if (Controller.index < Controller.tables.length)
	    Controller.tables[Controller.index].restore();
	else
	{
		Controller.restoring = false; 
		Controller.index = -1;
		Controller.main.invoke();
	}
}
 
function backup ()
{
	if (Controller.index < Controller.tables.length)
	    Controller.tables[Controller.index].backup();
	else
	{
		Controller.backingup = false; 
		Controller.index = -1;
		Controller.main.invoke();
	}
}
</script>
</head>



<body onload="app.start()" style="padding:10pt;margin:10pt">
 
 
<p style="font-family:'Lucida Grande', Georgia, 'Times New Roman', Times, serif"> 
<div style="width:100%;border-bottom:solid 1px #909090;margin-bottom:10px;padding-bottom:1px;color:#666"> 
<img src="http://www.101stratford.com/webservices/images/poweredby.gif"> 
<font style="font-size:16pt;font-family:'Lucida Grande', Georgia, 'Times New Roman', Times, serif" size="4">EventBuilder Professional Backup</font> 
</div> 
 
<div style="width:100%;font-family:Geneva, Arial, Helvetica, sans-serif;font-size:9pt;color:#666"> 
Welcome to the <strong>EventBuilder Professional</strong> backup controller. To backup your database, click 
the <strong>Backup</strong> button.
</div> 
</p> 
 


<table cellspacing="0" cellpadding="0" width="100%"> 
    <tr> 
        <td nowrap valign=top class="taboff"><div style="background-color:white;overflow:auto" id="dwork">loading...</div></td>
    </tr>
</table> 
</body>
</html>